package net.xiaoboli.mgp;

import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.api.GeneratedFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.internal.JDBCConnectionFactory;

import java.io.File;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.HashSet;
import java.util.Set;

public class PluginUtil {

    public static String firstCharToLowCase(String str) {
        char[] chars = new char[1];
        //String str="ABCDE1234";
        chars[0] = str.charAt(0);
        String temp = new String(chars);
        if (chars[0] >= 'A' && chars[0] <= 'Z') {
            return str.replaceFirst(temp, temp.toLowerCase());
        }
        return str;
    }

    public static String snakeToPascal(String input) {
        StringBuilder sb = new StringBuilder();
        String[] words = input.split("_");
        for (String word : words) {
            sb.append(word.substring(0, 1).toUpperCase());
            sb.append(word.substring(1).toLowerCase());
        }
        return sb.toString();
    }

    public static String snakeToCamel(String input) {
        StringBuilder sb = new StringBuilder();
        String[] words = input.split("_");
        int i = 0;
        for (String word : words) {
            if (i == 0) {
                sb.append(word.substring(0, 1).toLowerCase());
                i++;
            } else {
                sb.append(word.substring(0, 1).toUpperCase());
            }
            sb.append(word.substring(1).toLowerCase());
        }
        return sb.toString();
    }

    public static String modelToPath(String tableName) {
        String s = tableName.toLowerCase();
        s = s.replace("_", "/");
        return s;
    }

    public static String modelToName(String tableName) {
        String s = tableName.toLowerCase();
        s = s.replace("_", ".");
        return s;
    }


    public static boolean canWrite(GeneratedFile gf) {
        boolean canWrite = canWrite(gf.getTargetProject(), gf.getTargetPackage(), gf.getFileName());
        return canWrite;
    }

    public static boolean canWrite(String targetProject, String targetPackage, String filename) {
        String fp = Paths.get(targetProject, targetPackage.replace(".", "/"), filename).toString();
        if (new File(fp).exists()) {
            return false;
        }
        return true;
    }

    @SneakyThrows
    public static String canonicalPath(GeneratedFile gf) {
        String cPath = canonicalPath(gf.getTargetProject(), gf.getTargetPackage(), gf.getFileName());
        return cPath;
    }

    @SneakyThrows
    public static String canonicalPath(String targetProject, String targetPackage, String filename) {
        String fp = Paths.get(targetProject, targetPackage.replace(".", "/"), filename).toString();
        String cPath = new File(fp).getCanonicalPath();
        return cPath;
    }

    public static String packageName(IntrospectedTable introspectedTable, String _package) {
        return packageName(introspectedTable, _package, null);
    }

    public static String packageName(IntrospectedTable introspectedTable, String _package, String className) {
        String category = introspectedTable.getTableConfiguration().getProperty("category");
        if (StringUtils.isBlank(category)) {
            //附加首词
            String f = firstWord(introspectedTable);
            if (f != null) {
                _package = _package + "." + f;
            }
        } else if ("no".equals(category)) {
            //不附加
        } else {
            //附加特定值
            _package = _package + "." + category;
        }
        //
        if (StringUtils.isNotBlank(className))
            return _package + "." + className;
        //
        return _package;
    }

    public static String serviceName(IntrospectedTable introspectedTable, String servicePackage, String servicePrefix, String serviceSuffix) {
        String category = introspectedTable.getTableConfiguration().getProperty("category");
        if (StringUtils.isBlank(category)) {
            //附加首词
            String f = firstWord(introspectedTable);
            if (f != null) {
                servicePackage = servicePackage + "." + f;
            }
        } else if ("no".equals(category)) {
            //不附加
        } else {
            //附加特定值
            servicePackage = servicePackage + "." + category;
        }
        //
        String recordType = introspectedTable.getBaseRecordType();
        String modelName = recordType.substring(recordType.lastIndexOf(".") + 1);
        String serviceName = servicePackage + "." + servicePrefix + modelName + serviceSuffix;
        //
        return serviceName;
    }

    public static String serviceImplName(IntrospectedTable introspectedTable, String serviceImplPackage, String servicePrefix, String serviceSuffix) {
        String category = introspectedTable.getTableConfiguration().getProperty("category");
        if (StringUtils.isBlank(category)) {
            //附加首词
            String f = firstWord(introspectedTable);
            if (f != null) {
                if (serviceImplPackage.endsWith(".Impl")) {
                    serviceImplPackage = serviceImplPackage.substring(0, serviceImplPackage.length() - 5) + "." + f + ".Impl";
                } else if (serviceImplPackage.endsWith(".impl")) {
                    serviceImplPackage = serviceImplPackage.substring(0, serviceImplPackage.length() - 5) + "." + f + ".impl";
                } else {
                    serviceImplPackage = serviceImplPackage + "." + f;
                }
            }
        } else if ("no".equals(category)) {
            //不附加
        } else {
            //附加特定值
            if (serviceImplPackage.endsWith(".Impl")) {
                serviceImplPackage = serviceImplPackage.substring(0, serviceImplPackage.length() - 5) + "." + category + ".Impl";
            } else if (serviceImplPackage.endsWith(".impl")) {
                serviceImplPackage = serviceImplPackage.substring(0, serviceImplPackage.length() - 5) + "." + category + ".impl";
            } else {
                serviceImplPackage = serviceImplPackage + "." + category;
            }
        }
        //
        String recordType = introspectedTable.getBaseRecordType();
        String modelName = recordType.substring(recordType.lastIndexOf(".") + 1);
        String serviceImplName = serviceImplPackage + "." + servicePrefix + modelName + serviceSuffix + "Impl";
        //
        return serviceImplName;
    }

    public static String controllerName(IntrospectedTable introspectedTable, String controllerPackage) {
        String category = introspectedTable.getTableConfiguration().getProperty("category");
        if (StringUtils.isBlank(category)) {
            //附加首词
            String f = firstWord(introspectedTable);
            if (f != null) {
                controllerPackage = controllerPackage + "." + f;
            }
        } else if ("no".equals(category)) {
            //不附加
        } else {
            //附加特定值
            controllerPackage = controllerPackage + "." + category;
        }
        //
        String recordType = introspectedTable.getBaseRecordType();
        String modelName = recordType.substring(recordType.lastIndexOf(".") + 1);
        String controllerName = controllerPackage.concat(".").concat(modelName).concat("Controller");
        //
        return controllerName;
    }

    private static String firstWord(IntrospectedTable introspectedTable) {
        String tableName = introspectedTable.getTableConfiguration().getTableName();
        String[] items = tableName.split("_");
        if (items.length > 1) {
            return items[0];
        }
        return null;
    }

    @SneakyThrows
    public static Set<String> getIndexColumns(IntrospectedTable introspectedTable) {
        Set<String> nameSet = new HashSet<>();
        try (Connection connection = new JDBCConnectionFactory(introspectedTable.getContext().getJdbcConnectionConfiguration()).getConnection()) {
            DatabaseMetaData metaData = connection.getMetaData();
            String tableName = introspectedTable.getTableConfiguration().getTableName();
            try (ResultSet resultSet = metaData.getIndexInfo(null, null, tableName, false, false)) {
                while (resultSet.next()) {
                    String columnName = resultSet.getString("COLUMN_NAME");
                    nameSet.add(columnName);
                }
            }
        }
        return nameSet;
    }

    public static String nullDefault(String str, String _default) {
        if (str == null)
            return _default;
        return str;
    }


//    public static void mkdirs(String path) {
//        File file = new File(path);
//        if (!file.exists()) {
//            file.mkdirs();
//        }
//    }

}
